/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package tetris;

import java.awt.*;
import java.awt.event.*;
import java.util.LinkedList;
import javax.swing.*;


/**
 *
 * @author CJ
 */
public class GameEngine extends JPanel implements ActionListener, KeyListener {

    protected LinkedList blocks;
    protected final int WIDTH = 200;
    protected final int LENGTH = 380;
    protected final int STARTING_POINT = 50;

    protected final int SPEED = 150;

    protected Block current;
    protected Block next;
    protected Board b;

    protected Integer score = 0;

    protected boolean gameOver = false;

    public GameEngine()
    {
        initGraphics();
        initLists();
    }

    public void initLists()
    {
        blocks = new LinkedList();
        addRandomBlock();
        addRandomBlock();
        current = (Block)(blocks.get(0));
        b = new Board(WIDTH/10, LENGTH/10);
    }

    public void add_L_Block(){blocks.add(new L_Block(WIDTH/2, STARTING_POINT, SPEED, 'N', LENGTH, WIDTH));}
    public void add_R_Block(){blocks.add(new R_Block(WIDTH/2, STARTING_POINT, SPEED, 'N', LENGTH, WIDTH));}
    public void add_Square_Block(){blocks.add(new Square_Block(WIDTH/2, STARTING_POINT, SPEED, 'N', LENGTH, WIDTH));}
    public void add_Pound_Block(){blocks.add(new Pound_Block(WIDTH/2, STARTING_POINT, SPEED, 'N', LENGTH, WIDTH));}
    public void add_Pound_Inverse_Block(){blocks.add(new Pound_Inverse_Block(WIDTH/2, STARTING_POINT, SPEED, 'N', LENGTH, WIDTH));}
    public void add_Straight_Block(){blocks.add(new Straight_Block(WIDTH/2, STARTING_POINT, SPEED, 'N', LENGTH, WIDTH));}
    public void add_T_Block(){blocks.add(new T_Block(WIDTH/2, STARTING_POINT, SPEED, 'N', LENGTH, WIDTH));}

    public void initGraphics()
    {
        setPreferredSize(new Dimension(WIDTH, LENGTH));
        setFocusable(true);
        addKeyListener(this);
    }

    public void addRandomBlock()
    {
        int rand = (int)(Math.random() * 7);
        //System.out.println(rand);
        switch(rand)
        {
            case 0:
                add_L_Block();
                break;
            case 1:
                add_R_Block();
                break;
            case 2:
                add_Square_Block();
                break;
            case 3:
                add_Pound_Block();
                break;
            case 4:
                add_Pound_Inverse_Block();
                break;
            case 5:
                add_Straight_Block();
                break;
            case 6:
                add_T_Block();
                break;

        }
    }

    public void actionPerformed(ActionEvent event){
        if(gameOver)
        {
            repaint();
            return;
        }
        current = (Block)blocks.get(blocks.size()- 2);
        next = (Block)blocks.get(blocks.size() - 1);

        next.setX(WIDTH/5, b);
        next.setY(STARTING_POINT * 4/5);
        next.stopit();

        if(!current.stop())
            current.step(b, true);
        else
        {
            if(current.getY() < STARTING_POINT + 10)
            {
                gameOver = true;
                return;
            }
            addRandomBlock();
            score += b.clearRows(blocks);
            next.setX(WIDTH/2, b);
            next.setY(STARTING_POINT);
            next.moveit();
        }
        repaint();
    }

    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        if(gameOver)
            drawGameOver(g);
        else
        {
            drawBlocks(g);
            drawHeader(g);
        }
    }

    public void drawGameOver(Graphics g)
    {
        g.setColor(Color.black);
        g.drawString("GAME OVER", WIDTH/2 - 40, LENGTH/2);
        Integer temp = score * 100;
        g.drawString("Score : " + temp, WIDTH/20 - 35, LENGTH/2 + 10);
    }

    public void drawHeader(Graphics g)
    {
        //Draw Boxes at top
        g.setColor(Color.black);
        g.fillRect(0,
                0,
                WIDTH,
                STARTING_POINT * 4/5 - 10);
        g.fillRect(0,
                STARTING_POINT * 4/5 - 10,
                WIDTH/5 - 20,
                STARTING_POINT * 1/5 + 55);
        g.fillRect(0,
                STARTING_POINT + 30,
                WIDTH,
                15);
        g.fillRect(WIDTH/5 + 30,
                STARTING_POINT * 4/5 - 10,
                WIDTH * 4/5 - 30,
                STARTING_POINT * 1/5 + 55);

        //Draw Score
        g.setColor(Color.white);
        Integer temp = score * 100;
        g.drawString(temp.toString(), WIDTH - 40, 20);

        //This is all hard coded.. Damn
    }

    public void drawBlocks(Graphics g)
    {
        for(int i = 0; i < blocks.size(); i++)
        {
            ((Block)blocks.get(i)).draw(g, b);
        }
    }

    public void keyPressed(KeyEvent evt)
    {
        if(KeyEvent.VK_RIGHT == evt.getKeyCode())
            current.setX(current.getX() + 10, b);
        else if(KeyEvent.VK_LEFT == evt.getKeyCode())
            current.setX(current.getX() - 10, b);
        else if(KeyEvent.VK_UP == evt.getKeyCode())
            current.rotate();
        else if(KeyEvent.VK_SPACE == evt.getKeyCode())
        {
            while(!current.stop())
            {
                current.step(b, false);
            }
            /*int[][] test = b.getBoard();
            for(int row = 0;row<test.length;row++)
            {
                for(int col = 0;col<test[row].length;col++)
                    System.out.print(", " + test[row][col]);
                System.out.println();
            }*/
        }
        else if(KeyEvent.VK_DOWN == evt.getKeyCode())
            current.step(b, false);
    }

    public void keyReleased(KeyEvent evt)
    {

    }

    public void keyTyped(KeyEvent evt)
    {
        
    }
}
